﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Drawing;
using Axial.DOM;

namespace Axial
{
	public class Canvas : Control
	{
		public uint? Width { get; set; }
		public uint? Height { get; set; }

		protected override void Render(HtmlTextWriter writer)
		{
			base.Render(writer);

			writer.WriteBeginTag("canvas");
			writer.WriteAttribute("id", ClientID);
			if (Width.HasValue)
				writer.WriteAttribute("width", Width.ToString());
			if (Height.HasValue)
				writer.WriteAttribute("height", Height.ToString());
			writer.Write(">");
			writer.WriteEndTag("canvas");
		}

		public CanvasContext GetContext(string contextId) { return new CanvasContext(this); }

		public static explicit operator Canvas(Element e)
		{
			return new Canvas();
		}
	}

	// taken from http://www.whatwg.org/specs/web-apps/current-work/#canvasrenderingcontext2d
	public class CanvasContext
	{
		public Canvas Canvas { get; private set; }

		internal CanvasContext(Canvas canvas)
		{
			Canvas = canvas;
		}

		// state
		public void Save() { } // push state on state stack
		public void Restore() { } // pop state stack and restore state

		// transformations (default transform is the identity matrix)
		public void Scale(double x, double y) { }
		public void Rotate(double angle) { }
		public void Translate(double x, double y) { }
		public void Transform(double m11, double m12, double m21, double m22, double dx, double dy) { }
		public void SetTransform(double m11, double m12, double m21, double m22, double dx, double dy) { }

		// compositing
		public double GlobalAlpha { get; set; }
		public string GlobalCompositeOperation { get; set; }

		// colors and styles
		public string FillStyle { get; set; }
		public string StrokeStyle { get; set; }
		public CanvasGradient CreateLinearGradient(double x0, double y0, double x1, double y1) { return new CanvasGradient(); }
		public CanvasGradient CreateRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1) { return new CanvasGradient(); }
		public CanvasPattern CreatePattern(Axial.DOM.Image image, string repetition) { return new CanvasPattern(); }
		public CanvasPattern CreatePattern(System.Web.UI.WebControls.Image image, string repetition) { return new CanvasPattern(); }
		public CanvasPattern CreatePattern(Canvas image, String repetition) { return new CanvasPattern(); }

		// line caps/joins
		public double LineWidth { get; set; } // (default 1)
		public string LineCap { get; set; } // "butt", "round", "square" (default "butt")
		public string LineJoin { get; set; } // "round", "bevel", "miter" (default "miter")
		public double MiterLimit { get; set; } // (default 10)

		// shadows
		public double ShadowOffsetX { get; set; } // (default 0)
		public double ShadowOffsetY { get; set; } // (default 0)
		public double ShadowBlur { get; set; } // (default 0)
		public string ShadowColor { get; set; } // (default transparent black)

		// rects
		public void ClearRect(double x, double y, double w, double h) { }
		public void FillRect(double x, double y, double w, double h) { }
		public void StrokeRect(double x, double y, double w, double h) { }

		// path API
		public void BeginPath() { }
		public void ClosePath() { }
		public void MoveTo(double x, double y) { }
		public void LineTo(double x, double y) { }
		public void QuadraticCurveTo(double cpx, double cpy, double x, double y) { }
		public void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y) { }
		public void ArcTo(double x1, double y1, double x2, double y2, double radius) { }
		public void Rect(double x, double y, double w, double h) { }
		public void Arc(double x, double y, double radius, double startAngle, double endAngle, bool anticlockwise) { }
		public void Fill() { }
		public void Stroke() { }
		public void Clip() { }
		public bool IsPointInPath(double x, double y) { return false; }

		// text
		public string Font { get; set; } // (default 10px sans-serif)
		public string TextAlign { get; set; } // "start", "end", "left", "right", "center" (default: "start")
		public string TextBaseline { get; set; } // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
		public void FillText(string text, double x, double y) { }
		public void FillText(string text, double x, double y, double maxWidth) { }
		public void StrokeText(string text, double x, double y) { }
		public void StrokeText(string text, double x, double y, double maxWidth) { }
		public TextMetrics MeasureText(string text) { return new TextMetrics(); }

		// drawing images
		public void DrawImage(Axial.DOM.Image image, double dx, double dy) { }
		public void DrawImage(Axial.DOM.Image image, double dx, double dy, double dw, double dh) { }
		public void DrawImage(Axial.DOM.Image image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh) { }
		public void DrawImage(System.Web.UI.WebControls.Image image, double dx, double dy) { }
		public void DrawImage(System.Web.UI.WebControls.Image image, double dx, double dy, double dw, double dh) { }
		public void DrawImage(System.Web.UI.WebControls.Image image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh) { }
		public void DrawImage(Canvas image, double dx, double dy) { }
		public void DrawImage(Canvas image, double dx, double dy, double dw, double dh) { }
		public void DrawImage(Canvas image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh) { }

		// pixel manipulation
		public ImageData CreateImageData(double sw, double sh) { return new ImageData(); }
		public ImageData GetImageData(double sx, double sy, double sw, double sh) { return new ImageData(); }
		public void PutImageData(ImageData imagedata, double dx, double dy) { }
		public void PutImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight) { }
	}

	public class CanvasGradient
	{
		// opaque object
		public void AddColorStop(double offset, string color) { }
	}

	public class CanvasPattern
	{
		// opaque object
	}

	public class TextMetrics
	{
		public double Width { get; private set; }
	}

	public class ImageData
	{
		public ulong Width { get; private set; }
		public ulong Height { get; private set; }
		public CanvasPixelArray Data { get; private set; }
	}

	public class CanvasPixelArray
	{
		public ulong Length { get; private set; }
		public int this[int index] { get { return 0; } set { } }
	}
}
